/**
 * NeuroSky数据解析器
 * 
 * 用途：解析从NeuroSky设备接收的蓝牙数据包，提取各种脑波数据
 * 方法：借鉴成功项目的直接解析方式，简化数据处理流程
 * 原理：按照NeuroSky协议解析数据包，包括同步、校验和、数据提取
 */
package com.example.brain_wave.bluetooth.parser

import com.example.brain_wave.bluetooth.model.NeuroSkyRawData

class NeuroSkyDataParser {
    
    private var onDataReceived: ((NeuroSkyRawData) -> Unit)? = null
    
    // 数据变量
    private var attention: Int = 0
    private var meditation: Int = 0
    private var rawValue: Int = 0
    private var delta: Int = 0
    private var theta: Int = 0
    private var lowAlpha: Int = 0
    private var highAlpha: Int = 0
    private var lowBeta: Int = 0
    private var highBeta: Int = 0
    private var lowGamma: Int = 0
    private var midGamma: Int = 0
    private var poorSignal: Int = 0
    private var blinkStrength: Int = 0
    
    /**
     * 设置数据接收回调
     */
    fun setOnDataReceived(callback: (NeuroSkyRawData) -> Unit) {
        onDataReceived = callback
        println("NeuroSkyDataParser: 数据接收回调已设置")
    }
    
    /**
     * 处理接收到的蓝牙数据 - 借鉴成功项目的直接解析方式
     */
    fun processData(data: ByteArray) {
        // println("NeuroSkyDataParser: processData 被调用，数据长度: ${data.size}")
        parseData(data)
    }
    
    /**
     * 解析数据包 - 借鉴参考项目的成功实现
     */
    private fun parseData(data: ByteArray) {
        var i = 0
        while (i < data.size - 1) {
            // 查找包头 0xAA 0xAA
            if (data[i].toInt() and 0xFF == 0xAA && 
                data[i + 1].toInt() and 0xFF == 0xAA) {
                
                i += 2
                if (i >= data.size) break
                
                val payloadLength = data[i].toInt() and 0xFF
                i++
                
                if (i + payloadLength >= data.size) break
                
                // 提取payload
                val payload = ByteArray(payloadLength)
                System.arraycopy(data, i, payload, 0, payloadLength)
                i += payloadLength
                
                if (i >= data.size) break
                
                // 验证校验和
                val checksum = data[i].toInt() and 0xFF
                var calculatedChecksum = 0
                for (b in payload) {
                    calculatedChecksum += b.toInt() and 0xFF
                }
                calculatedChecksum = (calculatedChecksum.inv() and 0xFF)
                
                if (checksum == calculatedChecksum) {
                    parsePayload(payload)
                }
                i++
            } else {
                i++
            }
        }
    }
    
    /**
     * 解析payload数据 - 借鉴参考项目的实现
     */
    private fun parsePayload(payload: ByteArray) {
        var i = 0
        while (i < payload.size) {
            val code = payload[i].toInt() and 0xFF
            
            when (code) {
                0x02 -> { // Poor Signal
                    i++
                    if (i < payload.size) {
                        poorSignal = payload[i].toInt() and 0xFF
                    }
                }
                0x04 -> { // Attention
                    i++
                    if (i < payload.size) {
                        attention = payload[i].toInt() and 0xFF
                    }
                }
                0x05 -> { // Meditation
                    i++
                    if (i < payload.size) {
                        meditation = payload[i].toInt() and 0xFF
                    }
                }
                0x16 -> { // Blink Strength
                    i++
                    if (i < payload.size) {
                        blinkStrength = payload[i].toInt() and 0xFF
                    }
                }
                0x80 -> { // Raw Value
                    i++ // skip length
                    i++
                    if (i + 1 < payload.size) {
                        val val0 = payload[i].toInt() and 0xFF
                        val val1 = payload[i + 1].toInt() and 0xFF
                        rawValue = val0 * 256 + val1
                        if (rawValue > 32768) {
                            rawValue -= 65536
                        }
                        i++
                    }
                }
                0x83 -> { // ASIC EEG Power
                    i++ // skip length
                    if (i + 23 < payload.size) {
                        // Delta (3 bytes)
                        i++
                        val delta0 = payload[i].toInt() and 0xFF
                        val delta1 = payload[i + 1].toInt() and 0xFF
                        val delta2 = payload[i + 2].toInt() and 0xFF
                        delta = delta0 * 65536 + delta1 * 256 + delta2
                        i += 2
                        
                        // Theta (3 bytes)
                        i++
                        val theta0 = payload[i].toInt() and 0xFF
                        val theta1 = payload[i + 1].toInt() and 0xFF
                        val theta2 = payload[i + 2].toInt() and 0xFF
                        theta = theta0 * 65536 + theta1 * 256 + theta2
                        i += 2
                        
                        // Low Alpha (3 bytes)
                        i++
                        val lowAlpha0 = payload[i].toInt() and 0xFF
                        val lowAlpha1 = payload[i + 1].toInt() and 0xFF
                        val lowAlpha2 = payload[i + 2].toInt() and 0xFF
                        lowAlpha = lowAlpha0 * 65536 + lowAlpha1 * 256 + lowAlpha2
                        i += 2
                        
                        // High Alpha (3 bytes)
                        i++
                        val highAlpha0 = payload[i].toInt() and 0xFF
                        val highAlpha1 = payload[i + 1].toInt() and 0xFF
                        val highAlpha2 = payload[i + 2].toInt() and 0xFF
                        highAlpha = highAlpha0 * 65536 + highAlpha1 * 256 + highAlpha2
                        i += 2
                        
                        // Low Beta (3 bytes)
                        i++
                        val lowBeta0 = payload[i].toInt() and 0xFF
                        val lowBeta1 = payload[i + 1].toInt() and 0xFF
                        val lowBeta2 = payload[i + 2].toInt() and 0xFF
                        lowBeta = lowBeta0 * 65536 + lowBeta1 * 256 + lowBeta2
                        i += 2
                        
                        // High Beta (3 bytes)
                        i++
                        val highBeta0 = payload[i].toInt() and 0xFF
                        val highBeta1 = payload[i + 1].toInt() and 0xFF
                        val highBeta2 = payload[i + 2].toInt() and 0xFF
                        highBeta = highBeta0 * 65536 + highBeta1 * 256 + highBeta2
                        i += 2
                        
                        // Low Gamma (3 bytes)
                        i++
                        val lowGamma0 = payload[i].toInt() and 0xFF
                        val lowGamma1 = payload[i + 1].toInt() and 0xFF
                        val lowGamma2 = payload[i + 2].toInt() and 0xFF
                        lowGamma = lowGamma0 * 65536 + lowGamma1 * 256 + lowGamma2
                        i += 2
                        
                        // Mid Gamma (3 bytes)
                        i++
                        val midGamma0 = payload[i].toInt() and 0xFF
                        val midGamma1 = payload[i + 1].toInt() and 0xFF
                        val midGamma2 = payload[i + 2].toInt() and 0xFF
                        midGamma = midGamma0 * 65536 + midGamma1 * 256 + midGamma2
                        i += 2
                    }
                }
            }
            i++
        }
        
        // 创建数据对象并回调
        val data = NeuroSkyRawData(
            timestamp = System.currentTimeMillis(),
            attention = attention,
            meditation = meditation,
            rawValue = rawValue,
            delta = delta,
            theta = theta,
            lowAlpha = lowAlpha,
            highAlpha = highAlpha,
            lowBeta = lowBeta,
            highBeta = highBeta,
            lowGamma = lowGamma,
            midGamma = midGamma,
            poorSignal = poorSignal,
            blinkStrength = blinkStrength
        )
        
        // println("NeuroSkyDataParser: 准备调用onDataReceived回调 - onDataReceived=${onDataReceived != null}")
        onDataReceived?.invoke(data)
        // println("NeuroSkyDataParser: onDataReceived回调调用完成")
    }
}